/*
 * @Author: jingfuu@163.com
 * @Date: 2024-11-22 16:35:17
 * @LastEditTime: 2024-12-11 13:35:59
 * @Description: file content
 */
import {
  Body,
  Controller,
  Delete,
  Get,
  Inject,
  Logger,
  Param,
  Post,
  Put,
  Query,
  Res,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { RoleService } from '../service/RoleService';
import { RoleDto } from '../dto/RoleDto';
import PageResult from 'src/common/PageResult';
import { R } from 'src/common/R';
import RoleQueryParam from '../param/RoleQueryParam';
import MenuService from '../service/MenuService';
import ServiceException from 'src/common/ServiceException';
import { Response } from 'express';
import { PreAuthorize } from 'src/common/decorator/pre-authorize.decorator';
import BusinessType from 'src/common/enum/BusinessType';
import { Log } from 'src/common/decorator/log';

/*
 * @Author: jingfuu@163.com
 * @Date: 2024-11-22 16:35:17
 * @LastEditTime: 2024-11-25 11:12:00
 * @Description: 角色接口
 */
@ApiTags('角色接口')
@Controller('system/role')
class RoleController {
  private readonly logger = new Logger(RoleController.name);

  @Inject()
  private roleService: RoleService;

  @Inject()
  private menuService: MenuService;

  @PreAuthorize('system:role:list')
  @ApiOperation({ summary: '分页查询角色列表' })
  @Get('/list')
  async findRoleList(@Query() param: RoleQueryParam): Promise<R<RoleDto>> {
    this.logger.log('query role list start, param:' + JSON.stringify(param));
    const result: PageResult<RoleDto> = await this.roleService.list(param);
    return R.page<RoleDto>(result);
  }

  @Log({ title: '角色管理', businessType: BusinessType.UPDATE })
  @ApiOperation({ summary: '状态切换' })
  @Put('/changeStatus')
  async changeStatus(@Body() role: RoleDto) {
    this.logger.log('change role status start, role:' + JSON.stringify(role));
    return await this.roleService.updateRole(role);
  }

  @Log({ title: '角色管理', businessType: BusinessType.DELETE })
  @PreAuthorize('system:role:remove')
  @ApiOperation({ summary: '删除角色' })
  @Delete('/:id')
  async deleteRole(@Param('id') id: string): Promise<R<any>> {
    if (id.indexOf(',') > -1) {
      for (const item of id.split(',')) {
        await this.roleService.deleteRole(Number.parseInt(item));
      }
    } else {
      await this.roleService.deleteRole(Number.parseInt(id));
    }
    return R.ok();
  }

  @PreAuthorize('system:role:query')
  @ApiOperation({ summary: '获取角色详情' })
  @Get('/:id(\\d+)')
  async getRole(@Param('id') id: number): Promise<R<RoleDto>> {
    return R.ok(await this.roleService.getById(id));
  }

  @Log({ title: '角色管理', businessType: BusinessType.UPDATE })
  @PreAuthorize('system:role:edit')
  @ApiOperation({ summary: '修改角色' })
  @Put()
  async updateRole(@Body() role: RoleDto): Promise<R<void>> {
    // 校验role_key 重复
    await this.roleService.checkRoleKey(role.roleKey, role.roleId);
    await this.roleService.updateRole(role);
    return R.ok();
  }

  @Log({ title: '角色管理', businessType: BusinessType.INSERT })
  @PreAuthorize('system:role:add')
  @ApiOperation({ summary: '新增角色' })
  @Post()
  async addRole(@Body() role: RoleDto): Promise<R<void>> {
    await this.roleService.addRole(role);
    return R.ok();
  }

  @Log({ title: '角色管理', businessType: BusinessType.EXPORT })
  @PreAuthorize('system:role:export')
  @ApiOperation({ summary: '导出角色' })
  @Post('/export')
  async exportRole(@Query() param: RoleQueryParam, @Res() res: Response) {
    try {
      const buffer = await this.roleService.exportRole(param);
      res.set({
        'Content-Type': 'application/vnd.ms-excel',
        'Content-Disposition': 'attachment; filename=role.xlsx',
      });
      res.send(buffer);
    } catch (error) {
      this.logger.error('角色列表导出失败', error.stack);
      throw new ServiceException('角色列表导出失败');
    }
  }
}
export default RoleController;
